package elizaengine;

import java.io.*;
import java.util.Scanner;

import elizascript.ScriptInterop;

/**
 * The ElizaAPI class provides an outward-facing interface for using the
 * Eliza engine in your code.
 * 
 * Requires an InputStream and an OutputStream
 * 
 * @author Adam
 *
 */
public class ElizaAPI {
	private InputStream input;
	private OutputStream output;
	private Scanner scanner;
	
	public void setInputStream(InputStream Input)
	{
		input = Input;
	}
	public void setOutputStream(OutputStream Output)
	{
		output = Output;
	}
	
	public boolean run()
	{
		if(input == null || output == null)
		{
			return false;
		}
		else
		{
			// initialisation
			ScriptInterop ElizaScript = new ScriptInterop();
			ElizaScript.initialise("default.eli");
			
			Engine ElizaEngine = new Engine(ElizaScript);
			System.out.println(ElizaEngine.initialise());
			// Program running
			
			// Create a print writer with auto flush set to true
			PrintWriter outputWriter = new PrintWriter(output, true);
			
			while(ElizaEngine.shouldQuit())
			{
				// Print the output from Eliza when passed a line from the Input Stream
				outputWriter.println(
						ElizaEngine.getElizaResponse(
								getLineFromScanner() ) );
			}
			
			// If we required any clean up of the script or engine, we'd perform it here.
			return true;
		}
	}
	
	private String getLineFromScanner()
	{
		if(scanner == null)
		{
			// This mess is required to prevent a warning regarding unassigned 
			// closeable value something or other in Eclipse.
			try
			{
				// \A marks the beginning of the input boundary.
				// http://docs.oracle.com/javase/tutorial/essential/regex/bounds.html
				scanner = new Scanner(input, "UTF-8").useDelimiter("\n");
			}
			catch(IllegalArgumentException e)
			{
				System.out.println("Exception from Scanner construction");
				if(scanner != null)
					scanner.close();
									
				return "";
			}
		}
		String result = "";
		
		if (scanner.hasNext())
		{
			result = scanner.next();
		}
		
		return result;
	}
	public void cleanUp()
	{
		scanner.close();
	}
}
